/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rlpw.swing;

import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.event.EventListenerList;

/**
 *
 * @author weinpau
 */
public class JOCheckList<T> extends JOList<T> {

    private CheckModel<T> checked;
    private EventListenerList listeners = new EventListenerList();

    public JOCheckList() {
        this(new DefaultModel<T>());
    }

    public JOCheckList(Model<T> dm) {

        super(dm);
        checked = new DefaultCheckModel(this);
        setCellRenderer(new CheckListRenderer());

        addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {

                if (e.getX() > 18) {
                    return;
                }
                int index = locationToIndex(e.getPoint());
                getCheckModel().setChecked(index, !getCheckModel().isChecked(index));
                Rectangle rect = getCellBounds(index, index);
                repaint(rect);

                fireActionEvent();
            }
        });
    }

    @Override
    public CheckModel<T> getCheckModel() {
        return checked;
    }

    private class CheckListRenderer extends JCheckBox implements ListCellRenderer {

        public CheckListRenderer() {
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean hasFocus) {
            setEnabled(list.isEnabled());
            setSelected(getCheckModel().isChecked((T) value));
            setFont(list.getFont());
            setText(value.toString());

            if (isSelected) {
                setOpaque(true);
                setForeground(list.getSelectionForeground());
                setBackground(list.getSelectionBackground());
            } else {
                setOpaque(false);
                setForeground(list.getForeground());
                setBackground(list.getBackground());
            }


            return this;
        }
    }

    public void addActionListener(ActionListener l) {
        listeners.add(ActionListener.class, l);
    }

    public void removeActionListener(ActionListener l) {
        listeners.remove(ActionListener.class, l);
    }

    protected synchronized void fireActionEvent() {
        getDataModel().updateViews();
        ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "");
        for (ActionListener l : listeners.getListeners(ActionListener.class)) {
            l.actionPerformed(event);
        }
    }
}
